Spring ORM এবং Hibernate ব্যবহার করার সময় পারফরম্যান্স অপটিমাইজেশন গুরুত্বপূর্ণ। ডাটাবেস অ্যাক্সেসের সময় সঠিক কৌশলগুলি ব্যবহার না করলে অ্যাপ্লিকেশন ধীর হতে পারে এবং সার্ভারের ওপর অতিরিক্ত চাপ পড়তে পারে। এই সমস্যা সমাধানে বিভিন্ন পদ্ধতি ব্যবহার করা যায় যা ডাটাবেসের কার্যক্ষমতা বৃদ্ধি এবং সিস্টেমের পরিসর বজায় রাখে।
Lazy Loading হল একটি কৌশল যেখানে সম্পর্কিত ডেটা তখনই লোড হয় যখন তা প্রথমবার অ্যাক্সেস করা হয়। এটি অ্যাপ্লিকেশনের পারফরম্যান্সে বড় ধরনের প্রভাব ফেলতে পারে, বিশেষ করে যখন ডেটা ভলিউম বড় হয়।
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import java.util.List;
@Entity
public class Department {
@Id
private int id;
private String name;
@OneToMany(mappedBy = "department", fetch = jakarta.persistence.FetchType.LAZY)
private List<Employee> employees;
// Getter এবং Setter
}
এখানে, employees
সম্পর্কটি Lazy Loading হিসেবে কনফিগার করা হয়েছে, যার মানে হলো ডিপার্টমেন্ট অ্যাক্সেস করার সময় employees তালিকা তখনই লোড হবে, যখন তা ব্যবহৃত হবে।
যখন সম্পর্কিত ডেটা একসাথে প্রয়োজন হয়, তখন Eager Loading ব্যবহার করা উপকারী হতে পারে। এটি ডেটা লোড করার সময় সম্পর্কিত সব ডেটা একযোগে লোড করে।
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import java.util.List;
@Entity
public class Department {
@Id
private int id;
private String name;
@OneToMany(mappedBy = "department", fetch = jakarta.persistence.FetchType.EAGER)
private List<Employee> employees;
// Getter এবং Setter
}
এখানে, employees
সম্পর্কটি Eager Loading হিসেবে কনফিগার করা হয়েছে, যার মানে হলো যখন ডিপার্টমেন্ট লোড হবে, তখন employees সম্পর্কিত ডেটা একসাথে লোড হবে।
N+1 Query Problem হল একটি সাধারণ পারফরম্যান্স সমস্যা যেখানে একাধিক সম্পর্কিত ডেটা লোড করার সময় একাধিক অতিরিক্ত SQL কুয়েরি তৈরি হয়। এটি কার্যকরভাবে ডাটাবেসের ওপর অতিরিক্ত চাপ ফেলে এবং অ্যাপ্লিকেশনের পারফরম্যান্সকে কমিয়ে দেয়। এই সমস্যাটি সমাধান করতে JOIN FETCH ব্যবহার করা হয়।
import org.hibernate.Hibernate;
import org.hibernate.Session;
public class ProductService {
private Session session;
public ProductService(Session session) {
this.session = session;
}
public void fetchAllDepartments() {
List<Department> departments = session.createQuery("from Department d join fetch d.employees", Department.class).getResultList();
for (Department department : departments) {
Hibernate.initialize(department.getEmployees());
}
}
}
এখানে JOIN FETCH ব্যবহার করে একটিমাত্র কুয়েরি মাধ্যমে employees সম্পর্কিত ডেটা লোড করা হয়েছে, যার ফলে N+1 কুয়েরি সমস্যা থেকে মুক্তি পাওয়া গেছে।
Hibernate বা JPA-তে Batch Fetching ব্যবহার করে একাধিক সম্পর্কিত ডেটা একযোগে একাধিক ডাটাবেস কুয়েরি ব্যবহার করে লোড করা যায়। এটি একটি কার্যকরী কৌশল যেখানে একাধিক লোডিং অপারেশন একত্রে করা হয়, ফলে পারফরম্যান্স বৃদ্ধি পায়।
import org.hibernate.Session;
import org.hibernate.query.Query;
public class ProductService {
private Session session;
public ProductService(Session session) {
this.session = session;
}
public void fetchProducts() {
String hql = "from Product";
Query<Product> query = session.createQuery(hql, Product.class);
query.setFetchSize(50); // Batch fetching size
List<Product> products = query.list();
}
}
এখানে setFetchSize(50) ব্যবহার করে ৫০টি রেকর্ড একসাথে লোড করা হয়েছে, যা ডাটাবেসে কম কুয়েরি পাঠিয়ে পারফরম্যান্স উন্নত করতে সাহায্য করে।
Hibernate বা JPA-তে Second-Level Cache ব্যবহার করে ডাটাবেস থেকে পুনরায় ডেটা রিট্রিভ করার সময় ক্যাশিং এর মাধ্যমে পারফরম্যান্স বাড়ানো যায়। ক্যাশে ব্যবহারের মাধ্যমে ডাটাবেসে অতিরিক্ত কল করা কমানো হয় এবং অ্যাপ্লিকেশন দ্রুতগতিতে কাজ করে।
hibernate.cfg.xml
ফাইলে ক্যাশ সক্রিয় করা:
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
Entity ক্লাসে ক্যাশ যোগ করা:
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Product {
// ফিল্ড এবং Getter/Setter
}
এখানে, Second-Level Cache সক্রিয় করার মাধ্যমে Product Entity-এর ডেটা ক্যাশে সংরক্ষিত হবে, ফলে পুনরায় রিট্রিভ করার সময় দ্রুত পাওয়া যাবে।
পারফরম্যান্স অপটিমাইজেশন কৌশলগুলি অ্যাপ্লিকেশনটিকে আরও দ্রুত, দক্ষ এবং স্কেলেবল করে তোলে। Spring ORM ব্যবহার করলে এই কৌশলগুলি সহজে প্রয়োগ করা যায়, যার মাধ্যমে ডাটাবেস অ্যাক্সেস আরও কার্যকরী হয়।
Read more